`include "counter.v"
`include "injector.v"

module tmr #(parameter CYCLES_SEC = 100_000_000) (
	input clk,
	input reset_n,
	input [2 : 0] apply,
	input [2 : 0] inject,
	input [2 : 0] mode,
	output select,
	output fault
);

// save toggled state for each counter
(* keep="true" *) wire [2 : 0] toggled;
(* keep="true" *) wire [2 : 0] tampered;

// triple modular redundancy: at least two out of three bits set
assign select = (tampered[1] & tampered[0]) | (tampered[2] & tampered[1]) | (tampered[2] & tampered[0]);
// if one bit is different, we have a fault
// detects both kinds of faults, but stuck at only during high phases
// triggers reconfigurator
assign fault = ^tampered == 0;

injector injector_inst (
	.clk(clk),
	.reset_n(reset_n),
	.apply(apply),
	.inject(inject),
	.mode(mode),
	.original(toggled),
	.tampered(tampered)
);

counter #(.CYCLES_SEC (CYCLES_SEC)) counter_inst_0 (
	.clk(clk),
	.reset_n(reset_n),
	.toggled(toggled[0])
);

counter #(.CYCLES_SEC (CYCLES_SEC)) counter_inst_1 (
	.clk(clk),
	.reset_n(reset_n),
	.toggled(toggled[1])
);

counter #(.CYCLES_SEC (CYCLES_SEC)) counter_inst_2 (
	.clk(clk),
	.reset_n(reset_n),
	.toggled(toggled[2])
);
	
endmodule